const db = require("../models/index");
const { Op } = require("sequelize");
const user = require("../models/user");
const { regionTime } = require("../utils/regionTime");
const User = db.user;
const Project = db.project;
const Bug = db.bug;
const UserBug = db.user_bug;
const UserProject = db.user_project;
const History = db.bugHistory;

// 发布缺陷
exports.bugPublish = async (req, res) => {
  // 缺陷基本信息
  const { projectId, title, details, priority, severity, handlerArray } =
    req.body;

  // // 缺陷处理人数组
  const handlerArrayJson = JSON.stringify(handlerArray);
  // 获取用户信息作为缺陷创建人、变更人
  const realName = req.user.realName;
  const userId = req.user.id;

  if (!title) {
    return res.status(400).json({ code: 400, errorMsg: "标题不能为空" });
  }

  try {
    // 检查 projectId 是否存在
    const project = await Project.findOne({ where: { id: projectId } });
    if (!project) {
      return res.status(404).json({ code: 400, errorMsg: "项目不存在" });
    }

    const newBug = await Bug.create({
      creator: realName,
      creatorId: userId,
      projectId,
      projectName: project.projectName,
      title,
      details,
      priority,
      severity,
      handlerArray: handlerArrayJson,
      changerName: realName,
      changerId: userId,
      changeType: "新增",
    });

    if (handlerArray) {
      // 缺陷处理人数组
      const handlersId = handlerArray.map((handler) => {
        return handler.id;
      });

      // 建立缺陷与处理人之间的关联
      await newBug.setHandler(handlersId);
    }

    res.status(201).json({
      code: 201,
      msg: "缺陷创建成功",
      data: { bugId: newBug.id },
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ code: 500, errorMsg: error.message });
  }
};

//所在项目缺陷列表
exports.getProjectBugs = async (req, res) => {
  const projectId = req.params.projectId;

  try {
    //查询项目是否存在
    const project = await Project.findOne({ where: { id: projectId } });
    if (!project) {
      return res.status(404).json({ code: 404, errorMsg: "项目不存在" });
    }

    //查询该项目下的所有缺陷
    const bugs = await Bug.findAll({
      where: { projectId },
      attributes: [
        "id",
        "title",
        "details",
        "creator",
        "createdAt",
        "priority",
        "severity",
        "status",
        "handlerArray",
      ],
    });

    bugs.forEach((bug) => {
      bug.handlerArray = JSON.parse(bug.handlerArray);
    });

    res.status(201).json({
      code: 201,
      msg: "缺陷列表获取成功",
      data: bugs,
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ code: 500, errorMsg: error.message });
  }
};

//查看缺陷详情
exports.getBugDetail = async (req, res) => {
  const bugId = req.params.bugId;

  try {
    const bug = await Bug.findOne({
      where: { id: bugId },
      attributes: [
        "id",
        "title",
        "details",
        "creator",
        "creatorId",
        "projectId",
        "priority",
        "severity",
        "status",
        "handlerArray",
      ],
    });
    if (!bug) {
      return res.status(404).json({ code: 404, msg: "缺陷不存在" });
    }
    bug.handlerArray = JSON.parse(bug.handlerArray);

    const comments = await History.findAll({
      where: {
        bugId,
        comment: {
          [Op.ne]: null,
        },
      },
      attributes: ["id", "comment", "changerName", "updatedAt"],
      // order: [["id", "DESC"]],
    });

    // console.log(bug.createdAt);
    res.status(201).json({
      code: 201,
      msg: "缺陷详情获取成功",
      data: bug,
      comments,
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: error.message });
  }
};

// 缺陷流转/变更缺陷
exports.rollBug = async (req, res) => {
  const changerId = req.user.id;
  const changerName = req.user.realName;
  const { bugId, priority, severity, status, solution, comment, handlerArray } =
    req.body;
  try {
    //查询缺陷是否存在
    const bug = await Bug.findOne({
      where: { id: bugId },
    });
    if (!bug) {
      return res.status(404).json({ code: 404, errorMsg: "需求不存在" });
    }

    //重新建立缺陷与处理人之间的关联
    if (handlerArray) {
      const handlersId = handlerArray.map((handler) => {
        return handler.id;
      });
      await bug.setHandler(handlersId);
    }

    //更新缺陷
    const updatedBug = await bug.update({
      priority,
      severity,
      solution,
      status,
      handlerArray: JSON.stringify(handlerArray),
      changerId,
      changerName,
      changerType: "流转",
    });

    console.log(updatedBug.get({ plain: true }));

    res.status(201).json({ code: 201, msg: "缺陷已流转" });
  } catch (error) {
    console.error(error);
    res.status(500).json({ code: 500, errorMsg: error.message });
  }
};

//获取变更历史列表
exports.getBugHistory = async (req, res) => {
  const bugId = req.params.bugId;

  try {
    //history变更基本信息
    const historys = await History.findAll({
      where: {
        bugId,
      },
      attributes: [
        "id",
        "changedField",
        "updatedAt",
        "changerName",
        "changeType",
      ],
    });

    //afterUpdate变更后的值；beforeUpdate变更前的值
    let afterUpdate = [];
    let beforeUpdate = [];
    for (let i = 0; i < historys.length; i++) {
      //把实例转换成对象
      historys[i] = historys[i].get({ plain: true });
      historys[i].changedField = JSON.parse(historys[i].changedField);

      //时区转换
      historys[i].updatedAt = regionTime(historys[i].updatedAt);

      afterUpdate[i] = (
        await History.findOne({
          where: {
            bugId,
            id: historys[i].id,
          },
          attributes: historys[i].changeField,
        })
      ).dataValues;
      //缺陷处理人数组JSON转换
      if (afterUpdate[i].handlerArray) {
        afterUpdate[i].handlerArray = JSON.parse(afterUpdate[i].handlerArray);
      }

      //单独处理，后续将beforeUpdate数组中第一个对象的所有属性值设为“--”
      if (i === 0) {
        beforeUpdate[i] = (
          await History.findOne({
            where: {
              bugId,
              id: historys[i].id,
            },
            attributes: historys[i].changedFiled,
          })
        ).get({ plain: true });
      } else {
        beforeUpdate[i] = (
          await History.findOne({
            where: {
              bugId,
              id: historys[i].id,
            },
            attributes: historys[i].changedFiled,
          })
        ).get({ plain: true });
      }

      //映射对象存储字段名和对应的中文翻译
      const fieldTranslations = {
        title: "标题",
        details: "详情",
        priority: "优先级",
        solution: "解决方法",
        severity: "严重程度",
        status: "状态",
        handlerArray: "处理人",
        comment: "评论",
        creator: "创建人",
      };

      //将字段名转换为中文
      for (let j = 0; j < historys[i].changedField.length; j++) {
        const originalField = historys[i].changedField[j];
        if (fieldTranslations[originalField]) {
          historys[i].changedField[j] = fieldTranslations[originalField];
        }
      }

      //缺陷处理人数组JSON转化
      if (beforeUpdate[i].handlerArray) {
        beforeUpdate[i].handlerArray = JSON.parse(beforeUpdate[i].handlerArray);
      }
    }

    //将beforeUpdate数组中第一个对象的所有属性值设为"--"
    (function (arr) {
      if (arr.length > 0) {
        const firstObj = arr[0];
        for (let key in firstObj) {
          firstObj[key] = "--";
        }
      }
    })(beforeUpdate);

    //将属性值为null的字段设为"--"
    const handleNullFields = function (Array) {
      if (Array.length > 0) {
        for (let i = 1; i < beforeUpdate.length; i++) {
          const arr = Array[i];
          for (let key in arr) {
            if (!arr[key]) {
              arr[key] = "--";
            }
          }
        }
      }
    };
    handleNullFields(beforeUpdate);
    handleNullFields(afterUpdate);

    res.status(201).json({
      code: 201,
      msg: "缺陷历史",
      data: { bugId: bugId },
      historys,
      beforeUpdate,
      afterUpdate,
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: error.message });
  }
};

//编辑自己创建的缺陷标题、详情
exports.editBug = async (req, res) => {
  const bugId = req.params.bugId;
  const { title, details, priority, severity, solution, status, handlerArray } =
    req.body;

  try {
    //查询缺陷是否存在
    const bug = await Bug.findOne({
      where: { id: bugId },
    });
    if (!bug) {
      return res.status(400).json({ code: 404, errorMsg: "缺陷不存在" });
    }

    //重新建立缺陷与处理人之间的关联
    if (handlerArray) {
      const handlersId = handlerArray.map((handler) => {
        return handler.id;
      });
      await bug.setHandler(handlersId);
    }

    //更新缺陷
    const updatedBug = await bug.update({
      title,
      details,
      priority,
      severity,
      status,
      handlerArray: JSON.stringify(handlerArray),
      changerId: req.user.id,
      changerName: req.user.id,
      changerName: req.user.realName,
      changeType: "修改",
    });

    console.log(updatedBug);

    res.status(201).json({
      code: 201,
      msg: "缺陷已修改",
      data: { bugId: bugId },
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ code: 500, errorMsg: error.message });
  }
};

// 删除缺陷
exports.deleteBug = async (req, res) => {
  const bugId = req.params.bugId;

  try {
    //查询缺陷是否存在
    const bug = await Bug.findOne({
      where: { id: bugId },
    });
    if (!bug) {
      return res.status(404).json({ code: 404, errorMsg: "缺陷不存在" });
    }
    console.log("____");

    //记录缺陷变更历史
    await bug.update({
      status: "已删除",
      changerId: req.user.id,
      changerName: req.user.realName,
      changeType: "删除",
    });

    //删除缺陷
    await bug.destroy();

    res.status(201).json({
      code: 201,
      msg: "缺陷已删除",
      data: { bugId: bugId },
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ code: 500, errorMsg: error.message });
  }
};

//恢复缺陷
exports.restoreBug = async (req, res) => {
  const bugId = req.params.bugId;

  try {
    console.log(Bug.options.paranoid);

    //查询缺陷是否存在
    const bug = await Bug.findOne({
      where: { id: bugId },
    });
    // const bug = await Bug.findByPk(bugId, { paranoid: false });
    if (!bug) {
      return res.status(404).json({ code: 404, errorMsg: "缺陷不存在" });
    }

    //恢复缺陷
    const bugRestored = await bug.update({
      status: "规划中",
      changerId: req.user.id,
      changerName: req.user.realName,
      changeType: "恢复",
    });

    res.status(201).json({
      code: 201,
      msg: "缺陷已恢复",
      data: { bugId: bugId },
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ code: 500, errorMsg: error.message });
  }
};
